#pragma once

class ForwardDecA
{
public:
	ForwardDecA() { m_piArray = new int[100]; };
	~ForwardDecA()
	{
		if (m_piArray)
		{
			delete[]m_piArray;
			m_piArray = nullptr;
		}
	}
public:
	int* m_piArray;
};




#pragma once


class ForwardDecA;
class ForwardDecB
{
public:
	ForwardDecB() { m_piArray = new int[100]; };
	// CodeError!!! this will have memory leaks!!! 
	~ForwardDecB()
	{
		if (m_piArray)
		{
			delete[]m_piArray;
			m_piArray = nullptr;
		}

		if (m_pkA)
		{
			delete m_pkA;
		}
	}
	void SetForwardA(ForwardDecA* _pkA)
	{
		m_pkA = _pkA;
	}

public:
	int* m_piArray;
	ForwardDecA* m_pkA;

	//Compile Error!
	//ForwardDecA m_kAInstance;
};



1.C++的前向声明与内存泄漏

前向声明一般用于解决头文件相互包含问题或者省去包含引用头文件，但对应的也有一些限制或者弊端。
1. 只能用于指针，引用，函数传参该类型的指针，引用
2. 不能用于定义对象，成员，以及任何形式的访问，因为这时编译器只知有这个类型存在，但不知道具体大小与内容。
3. 不用包含头文件，可以缩短编译时间
4. 一般可以解决两个类相互使用问题，通常接口编程会用的比较多。
5. ！！！如果一个A类内部有内存分配，且使用前向声明，在B中进行维护，通常容易引发内存泄漏，因为这时A称为incomplete type，不会调用到A的析构函数。

现在编译器都有提示了，能发现这类错误！！！


#include <iostream>
// ！！！forwardB.h一定要在forwardA.h前面，这样才能做到不知道ForwardDecA
// 具体定义，变成一个incomplete type
#include "forwardB.h"
#include "forwardA.h"


#define _DEBUG 1

int main() {

#ifdef _DEBUG
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
    _CrtSetDebugFillThreshold(0);
#endif

    std::cout << "hello world" << std::endl;
    ForwardDecB kForwardB = ForwardDecB();
    // CodeError!!! memory leaks!!! 
    kForwardB.SetForwardA(new ForwardDecA);

    return 0;
}